Skip to content

feat(core): sourceMutation data-hf-id targeting (R1, T7)#1272

Draft
vanceingalls wants to merge 2 commits into
06-07-feat_studio_sourcepatcher_data-hf-id_targeting_r1_t3_from
06-07-feat_core_sourcemutation_data-hf-id_targeting_r1_t7_
Draft

feat(core): sourceMutation data-hf-id targeting (R1, T7)#1272
vanceingalls wants to merge 2 commits into
06-07-feat_studio_sourcepatcher_data-hf-id_targeting_r1_t3_from
06-07-feat_core_sourcemutation_data-hf-id_targeting_r1_t7_

Conversation

@vanceingalls
Copy link
Copy Markdown
Collaborator

@vanceingalls vanceingalls commented Jun 8, 2026

What

Adds hfId targeting to sourceMutation (packages/core/src/studio-api/helpers/sourceMutation.ts) and closes a CSS injection gap.

New targeting field:

export interface SourceMutationTarget {
  id?: string | null;
  hfId?: string;        // ← new
  selector?: string;
  selectorIndex?: number;
}

findTargetElement tries hfId first via findByHfId, then id, then selector.

CSS injection guard:

function escapeCssAttrValue(value: string): string {
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"'); }

A crafted value like hf-1234"][data-x="y would otherwise produce a valid compound selector that silently matches the wrong element.

Stable id protection: data-hf-id is blocked in both attribute and html-attribute op cases — it can never be overwritten by a patch operation.

Split clone cleanup: splitElementInHtml removes data-hf-id from the cloned element so the next parse mints a fresh stable id for the new half.

probeElementInSource updated to accept hfId as a valid probe target.

Why

T7 spec — the server-side mutation API (files.ts route) uses sourceMutation to apply patches to composition source files. It needs to accept hfId targeting for the same reason as sourcePatcher (T3): stable R1 ids must be usable as mutation targets from all surfaces. Depends on PR #1270.

The injection fix is a security correctness issue: without it, a user-controlled hfId value could produce a CSS selector that matches an unintended element.

How

  • escapeCssAttrValue: escapes \ before " (order matters — escaping " first would double-escape the backslash)
  • findByHfId wraps the selector call in try/catch in case the escaped value still somehow produces an invalid selector
  • splitElementInHtml clone: clone.removeAttribute("data-hf-id") before inserting — stable id must be unique; the parser will mint a new one on next round-trip

Test plan

  • T7 spec tests in sourceMutation.test.ts — hfId targeting, injection guard, attribute protection
  • 42 tests pass, 0 fail

vanceingalls and others added 2 commits June 7, 2026 20:51
Elements now get data-hf-id minted by ensureHfIds; parser reads
data-hf-id as model id, so HTML id attrs are no longer the model id.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator Author

vanceingalls commented Jun 8, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@vanceingalls vanceingalls marked this pull request as draft June 8, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant